<template>
  <div>
    <span style="font-size: 13px"
      >注意：该列表存在的字段服务端都会校验其规则 显示开关仅能控制前端是否校验规则</span
    >
    <el-table :data="addJson" height="67vh" row-key="id" border stripe style="width: 100%">
      <el-table-column type="expand">
        <template #default="scope">
          <el-form :inline="true" size="small" :model="scope" class="demo-form-inline">
            <span>
              <el-tabs v-model="settingTab">
                <el-tab-pane label="基础设置" name="BASE"
                  ><!--MD5加密-->
                  <el-form-item label="MD5加密" v-if="scope.row.type.value === 'text'">
                    <el-switch size="small" v-model="scope.row.type.text.md5" />
                  </el-form-item>
                  <!--类型配置-->
                  <template v-if="scope.row.type.value === 'select'">
                    <el-form-item label="选项数据源">
                      <el-select
                        v-model="scope.row.type.select.optionId"
                        filterable
                        placeholder="Select"
                        size="small"
                        @change="selectDataSource"
                        style="width: 160px"
                      >
                        <el-option
                          v-for="(item, index) in options.options"
                          :key="index"
                          :label="item.name"
                          :value="item.id"
                        /> </el-select></el-form-item
                    ><el-form-item label="允许创建">
                      <el-switch v-model="scope.row.type.select.allowCreate" /> </el-form-item
                    ><el-form-item label="多选">
                      <el-switch v-model="scope.row.type.select.multiple" />
                    </el-form-item>
                    <el-form-item label="多选/数量限制(0或空表示不限制)">
                      <el-input-number
                        controls-position="right"
                        v-model="scope.row.type.select.multipleLimit"
                      /> </el-form-item
                    ><el-form-item label="树状">
                      <el-switch v-model="scope.row.type.select.tree" /> </el-form-item
                  ></template>

                  <el-form-item label="宽度 140|320|520">
                    <el-input-number controls-position="right" v-model="scope.row.width" />
                  </el-form-item>
                  <span v-if="scope.row.type.value.includes('upload')">
                    <el-form-item label="上传限制大小/KB">
                      <el-input-number
                        controls-position="right"
                        v-model="scope.row.type.upload.size"
                      />
                    </el-form-item>
                    <el-form-item label="超出限制大小自动压缩">
                      <el-switch v-model="scope.row.type.upload.compress" />
                    </el-form-item>
                    <el-form-item label="上传限制数量">
                      <el-input-number
                        controls-position="right"
                        v-model="scope.row.type.upload.num"
                      />
                    </el-form-item>
                    <el-form-item label="允许上传的文件类型">
                      <el-tag
                        v-for="tag in scope.row.type.upload.type"
                        :key="tag"
                        closable
                        round
                        :disable-transitions="false"
                        @close="uploadTypeClose($event, scope.row)"
                      >
                        {{ tag }}
                      </el-tag>
                      <el-input
                        v-if="inputVisible"
                        ref="InputRef"
                        v-model="inputValue"
                        class="w-20"
                        size="small"
                        @keyup.enter="handleInputConfirm(scope.row)"
                        @blur="handleInputConfirm(scope.row)"
                      />
                      <el-button v-else class="button-new-tag" size="small" @click="showInput">
                        + New Tag
                      </el-button>
                    </el-form-item>
                  </span>
                  <!--元数据占位符-->
                  <el-form-item label="元数据占位符">
                    <el-switch size="small" v-model="scope.row.metadataPlaceholder" />
                  </el-form-item>
                  <!--默认值-->
                  <el-form-item v-if="scope.row.type.value.indexOf('upload') === -1" label="默认值">
                    <el-input
                      v-if="scope.row.type.value === 'text'"
                      v-model="scope.row.default"
                      clearable
                    />
                    <el-input
                      v-else-if="scope.row.type.value === 'password'"
                      v-model="scope.row.default"
                      type="password"
                      show-password
                    />
                    <el-input
                      v-if="scope.row.type.value === 'textarea'"
                      type="textarea"
                      :autosize="{ minRows: 2, maxRows: 4 }"
                      v-model="scope.row.default"
                      clearable
                      style="width: 240px"
                    />
                    <el-input-number
                      v-else-if="scope.row.type.value === 'number'"
                      v-model="scope.row.default"
                    />
                    <el-date-picker
                      v-else-if="scope.row.type.value === 'date'"
                      v-model="scope.row.default"
                      type="date"
                      style="width: 115px"
                    />
                    <el-date-picker
                      v-else-if="scope.row.type.value === 'datetime'"
                      v-model="scope.row.default"
                      type="datetime"
                      style="width: 145px"
                    />
                    <el-time-picker
                      v-else-if="scope.row.type.value === 'time'"
                      v-model="scope.row.default"
                      style="width: 115px"
                    />
                    <el-switch
                      v-else-if="scope.row.type.value === 'switch'"
                      v-model="scope.row.default"
                    />
                    <template v-else-if="scope.row.type.value === 'select'">
                      <template v-if="optionDatas[scope.row.type.select.optionId]">
                        <!-- 树形选项 -->
                        <el-tree-select
                          v-if="scope.row.type.select.tree"
                          v-model="scope.row.default"
                          :data="optionDatas[scope.row.type.select.optionId].options"
                          :multiple="scope.row.type.select.multiple"
                          :render-after-expand="false"
                          show-checkbox
                          style="width: 240px"
                        />
                        <!-- 选项 -->
                        <el-select
                          v-else
                          :multiple="scope.row.type.select.multiple"
                          filterable
                          v-model="scope.row.default"
                          placeholder="Select"
                          size="small"
                          style="width: 160px"
                        >
                          <el-option
                            v-for="(item, index) in optionDatas[scope.row.type.select.optionId]
                              .options"
                            :key="index"
                            :label="item.label"
                            :value="item.value"
                          />
                        </el-select>
                      </template>
                    </template>
                    <div v-else-if="scope.row.type.value === 'json'">
                      <div style="color: brown" v-if="scope.row.default === ''">
                        注意:
                        切换Json编辑器时需要有一个初始值,若无,请切换到文本或其他模类型添加初始值再切换会Json编辑器
                      </div>
                      <JsonEditView style="width: 800px" v-model="scope.row.default" />
                    </div>

                    <div v-else-if="scope.row.type.value === 'editor'">
                      <div style="color: brown">
                        注意：该编辑器界面上只同时能存在一个,否则会产生失去焦点异常
                      </div>
                      <WangEditorView style="width: 760px" v-model="scope.row.default" />
                    </div>
                    <MonacoEdit
                      v-else-if="scope.row.type.value === 'JavaScript'"
                      v-model="scope.row.default"
                      style="width: 800px"
                    />
                  </el-form-item>
                </el-tab-pane>
                <el-tab-pane label="规则设置" name="RULE">
                  <Rule v-model:rule="scope.row.rule" v-model:serviceRule="scope.row.serviceRule" />
                </el-tab-pane>
              </el-tabs>
            </span>
          </el-form>
        </template>
      </el-table-column>
      <!--表格-->
      <el-table-column label="关联网格字段" width="230" prop="type">
        <template #default="scope">
          <el-select
            v-model="scope.row.gridField"
            filterable
            @change="selectField($event, scope.row)"
            placeholder="未关联"
            size="small"
          >
            <el-option
              v-for="item in fieldJsonCopy"
              :key="item.field"
              :label="item.label"
              :value="item.field"
              :disabled="item.disabled"
            >
              <span style="float: left">{{ item.label }}</span>
              <span style="float: right; color: var(--el-text-color-secondary); font-size: 13px">
                {{ item.field }}
              </span></el-option
            >
          </el-select>
        </template>
      </el-table-column>
      <el-table-column
        label="显示"
        prop="isShow"
        width="70"
        :filters="[
          { text: '显示', value: true },
          { text: '隐藏', value: false }
        ]"
        :filter-method="filterHandler"
      >
        <template #default="scope">
          <el-switch size="small" v-model="scope.row.isShow" />
        </template>
      </el-table-column>
      <el-table-column label="名称" prop="name">
        <template #default="scope">
          <el-input v-model="scope.row.label" size="small" clearable />
        </template>
      </el-table-column>
      <el-table-column label="字段名" prop="field">
        <template #default="scope">
          <el-input
            v-model="scope.row.field"
            :disabled="!!scope.row.gridField"
            size="small"
            clearable
          />
        </template>
      </el-table-column>
      <el-table-column label="类型" width="110" prop="type">
        <template #default="scope">
          <el-select v-model="scope.row.type.value" placeholder="Select" size="small">
            <el-option
              v-for="(item, index) in editTypes"
              :key="index"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="220" style="gap: 10px" prop="isSort">
        <template #default="scope">
          <el-popconfirm placement="left" :hide-after="0" :hide-icon="true" title="选择同步到模版">
            <template #reference>
              <el-button icon="Switch" size="small" type="primary" style="margin-right: 10px" />
            </template>
            <template #actions="{ confirm, cancel }">
              <el-checkbox-group
                v-model="checkList"
                style="margin-bottom: 10px; display: flex; flex-direction: column"
              >
                <el-checkbox label="EDIT" value="EDIT" size="small" />
                <el-checkbox label="IMPORT" value="IMPORT" size="small" />
              </el-checkbox-group>
              <el-button size="small" @click="cancel">取消</el-button>
              <el-button type="danger" size="small" @click="syncField(scope.row, confirm)">
                确认
              </el-button>
            </template>
          </el-popconfirm>
          <OperationView v-model="addJson" :scope />
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>
<script lang="ts" setup>
import { ElMessage } from 'element-plus'
import JsonEditView from '@/views/template/util/JsonEditView.vue'
import WangEditorView from '@/views/template/util/WangEditorView.vue'
import MonacoEdit from '@/views/template/util/MonacoEdit.vue'
import OperationView from './OperationView.vue'
import Rule from './module/Rule.vue'
import { ref, nextTick } from 'vue'
import { useOptionDataStore } from '@/stores/optionData'
import { storeToRefs } from 'pinia'
const storeOptionData = useOptionDataStore()
const { optionDatas, options } = storeToRefs(storeOptionData)
// 字段配置列表
const props = defineProps(['fieldJson', 'editJson', 'importJson'])
// 解除与 fieldJson 双向绑定，改为单向
const fieldJsonCopy = ref(JSON.parse(JSON.stringify(props.fieldJson)))
const addJson = defineModel({ default: [] })
const settingTab = ref('BASE')
// const addJson = [
//   {
//     field: 'default',
//     label: '默认',
//     isShow: true,
//     type: {
//       value: 'select',
//       text: {
//         md5:false
//       },
//       select: {
//         optionId:'',
//         tree:false,
//         allowCreate:false,
//         multiple:false,
//         multipleLimit:0
//       },
//       upload: {
//         size: '100',
//         type: ['txt', 'pdf'],
//         compress: false,
//         num: 1
//       }
//     },
//     default: '222',
//     gridField: null, // 绑定网格字段
//     rule:"()=> [\r\n    {\r\n        required : true \r\n        }\r\n    ]",
//     serviceRule: {required: true},
//     width: 160
//   }
// ]

// 初始化一些数据
load()
async function load() {
  // 刷新选项列表
  storeOptionData.refreshOptions()
  // 已选择的关联字段标记为不可选
  addJson.value.forEach(async (item) => {
    // item.type.text = { md5: false }
    fieldJsonCopy.value.forEach((item2) => {
      if (item.field === item2.field) {
        item2.disabled = true
      }
    })
    // 初始化所有选项类型数据源
    if (item.type.value.indexOf('select') !== -1 && item.type.select.optionId) {
      await storeOptionData.add(item.type.select.optionId)
    }
  })
}
// 添加数据类型
const editTypes = [
  {
    value: 'text',
    label: '文本'
  },
  {
    value: 'password',
    label: '密码'
  },
  {
    value: 'textarea',
    label: '文本域'
  },
  {
    value: 'number',
    label: '数字'
  },
  {
    value: 'select',
    label: '选项'
  },
  {
    value: 'date',
    label: '日期'
  },
  {
    value: 'datetime',
    label: '日期时间'
  },
  {
    value: 'time',
    label: '时间'
  },
  {
    value: 'upload',
    label: '文件上传'
  },
  {
    value: 'upload_image',
    label: '图片上传'
  },
  {
    value: 'switch',
    label: '开关'
  },
  {
    value: 'json',
    label: 'json'
  },
  {
    value: 'JavaScript',
    label: 'JavaScript'
  },
  {
    value: 'editor',
    label: '富文本'
  }
]

const inputValue = ref('')
const inputVisible = ref(false)
const InputRef = ref()
// 删除文件上传类型
function uploadTypeClose(tag, row) {
  row.type.upload.type.splice(row.type.upload.type.indexOf(tag), 1)
}
// 添加文件上传类型时输入框获得焦点
function showInput() {
  inputVisible.value = true
  nextTick(() => {
    InputRef.value.input.focus()
  })
}
// 添加文件上传类型
function handleInputConfirm(row) {
  if (inputValue.value) {
    row.type.upload.type.push(inputValue.value.toLowerCase())
  }
  inputVisible.value = false
  inputValue.value = ''
}

// 选择选项数据源事件
async function selectDataSource(optionId) {
  await storeOptionData.add(optionId)
}

function selectField(selectfield, field) {
  fieldJsonCopy.value.forEach((item) => {
    if (item.field === selectfield) {
      // 该字段标记为不可选
      item.disabled = true
      // 释放原绑定对象网格字段为可选
      if (field.gridField) {
        fieldJsonCopy.value.forEach((item2) => {
          if (item2.field === field.field) {
            item2.disabled = false
          }
        })
      }
      // 配置同步网格字段
      field.field = item.field
      field.label = item.label
      field.type.value = editTypes[0].value
    }
  })
}
// 过滤字段
function filterHandler(value, row, column) {
  return row.isShow === value
}
// 同步字段
const checkList = ref([])
function syncField(row, confirm) {
  if (checkList.value.includes('EDIT')) {
    props.editJson.forEach((item) => {
      if (item.field === row.field) {
        for (const key in item) {
          item[key] = row[key]
        }
        ElMessage({
          message: '同步到EDIT配置！',
          type: 'success'
        })
        return
      }
    })
  }

  if (checkList.value.includes('IMPORT')) {
    props.importJson.fields.forEach((item) => {
      if (item.field === row.field) {
        for (const key in item) {
          // 跳过
          if (row[key] === undefined || key === 'isShow') {
            continue
          }
          // 判断是否导入设置不存在的数据类型
          if (key === 'type' && !['text', 'select'].includes(row[key].value)) {
            // 统一转换为text类型
            item[key] = {
              value: 'text',
              select: {
                optionId: ''
              }
            }
          } else {
            item[key] = row[key]
          }
        }
        ElMessage({
          message: '同步到IMPORT配置！',
          type: 'success'
        })
        return
      }
    })
  }
  // 确认关闭弹窗
  confirm()
}
</script>
<style scoped>
.el-form {
  margin: 0px 10px;
}
:deep(.el-table__expanded-cell) {
  background-color: hsl(0, 0%, 95%) !important;
}
:deep(.jsoneditor-vue) {
  height: 300px !important;
}
</style>
